﻿using System;
using System.Linq;
using QDT.Common;
using QDT.Core;
using QDT.Core.Domain;
using QDT.Core.Members;
using QDT.Core.Orders;
using QDT.Core.Payments;
using QDT.P2B.Domain.Config;
using QDT.P2B.Domain.Messages;
using QDT.Payment;

namespace QDT.Services.Orders {

    public class OrderService : ServiceBase, IOrderService {
        #region Implementation of IOrderService

        /// <summary>
        /// 创建一个充值订单
        /// </summary>
        /// <param name="userid"></param>
        /// <param name="money"></param>
        /// <param name="paymentkey"></param>
        /// <param name="bank"></param>
        /// <returns></returns>
        public ChargeOrder CreateChargeOrder(User user, decimal money, string paymentkey, string bank) {

            var order = new ChargeOrder(user.ID, GenerateOrderNumber(),money)
            {
                PaymentKey = paymentkey, 
                BankCode = bank,
            };

            order.Add("客户","您提交了充值订单,等待支付");

            DbProvider.Add(order);

            DbProvider.SaveChanges();

            return order;
        }

        /// <summary>
        /// 根据订单ID创建支付订单
        /// </summary>
        /// <param name="orderid"></param>
        /// <returns></returns>
        public PaymentNotice CreatePaymentOrder(int orderid) {

            var order = DbProvider.GetByID<ChargeOrder>(orderid);
            PaymentNotice notice;

            if (DbProvider.D<PaymentNotice>().Any(x=>x.OrderId==orderid))
            {
                notice = DbProvider.D<PaymentNotice>().FirstOrDefault(x => x.OrderId == orderid);
            }
            else
            {
                notice = new PaymentNotice(order);
                DbProvider.Add(notice);
            }

            DbProvider.SaveChanges();

            return notice;

        }

        public void AdminPay(AdminUser admin,ChargeOrder order) {
            
            order.AdminProcess(admin.Name,"管理员收款");

            var user = DbProvider.GetByID<User>(order.UserID);

            var userlog = user.Transaction(UserTransLog.TradeType.Charge, order.PayAmount, "", "充值订单{0},通过管理员后台充值成功".FormatWith(order.OrderSN));
            user.UserAccount.CurrentChargeMoney += order.PayAmount;

            DbProvider.Add(userlog);

            if (SettingManager.Get<MessageConfig>().SmsOpen && user.MobilePassed) {
                var msg = new MsgQueueFactory().CreateInchargeMsg(user.Mobile, order.PayAmount, order.OrderSN);
                DbProvider.Add(msg);
            }

            DbProvider.SaveChanges();

        }

        public void DeleteOrder(int[] id)
        {
            foreach (var order in id.Select(i => DbProvider.GetByID<ChargeOrder>(i)))
            {
                order.IsDelete = true;
            }
            DbProvider.SaveChanges();
        }

        public void ForeverDeleteOrder(int[] id)
        {
            foreach (var order in id.Select(i => DbProvider.GetByID<ChargeOrder>(i)))
            {
                DbProvider.Delete(order);
            }
            DbProvider.SaveChanges();
        }

        public void RestoreOrder(int[] id)
        {
            foreach (var order in id.Select(i => DbProvider.GetByID<ChargeOrder>(i)))
            {
                order.IsDelete = false;
            }
            DbProvider.SaveChanges();
        }

        public void PayFinished(object sender)
        {
            var po = sender as PaymentOrder;
            var notice = DbProvider.D<PaymentNotice>().FirstOrDefault(x => x.NoticeSn == po.PaymentNo && !x.IsPaid);
            if (notice == null) return;
            notice.Memo = "支付成功";
            notice.IsPaid = true;
            notice.PayTime = DateTime.Now;

            var order = DbProvider.GetByID<ChargeOrder>(notice.OrderId);
            if (order == null) return;

            //以处理过订单，不再处理，避免管理员处理过后，第三方才返回通知，重复充值
            if (order.Status == ChargeOrderStatus.Completed) return;

            order.Status = ChargeOrderStatus.Completed;
            order.PayAmount = po.Money;
            order.UpdateTime = DateTime.Now;

            order.Add("系统", "通过第三方支付成功");

            var user = DbProvider.GetByID<User>(order.UserID);

            var info = "支付成功{0}".FormatWith(order.OrderSN);
            var userlog = user.Transaction(UserTransLog.TradeType.Charge, order.PayAmount, "", info);
            user.UserAccount.CurrentChargeMoney += order.PayAmount;

            DbProvider.Add(userlog);

            if (SettingManager.Get<MessageConfig>().SmsOpen && user.MobilePassed)
            {
                var msg = new MsgQueueFactory().CreateInchargeMsg(user.Mobile, order.PayAmount, order.OrderSN);
                DbProvider.Add(msg);
            }

            DbProvider.SaveChanges();
        }

        public void PayFaild(object sender)
        {
            var po = sender as PaymentOrder;
            var notice = DbProvider.D<PaymentNotice>().FirstOrDefault(x => x.NoticeSn == po.PaymentNo);

            if (notice == null) return;
            notice.Memo = "第三方支付失败：" + po.Description;
            notice.IsPaid = false;

            var order = DbProvider.GetByID<ChargeOrder>(notice.OrderId);
            if (order == null) return;

            order.Status = ChargeOrderStatus.Failure;
            order.Memo = "支付出错";
            order.UpdateTime = DateTime.Now;

            order.Add("系统", "订单状态改变,第三方支付失败");
            DbProvider.SaveChanges();
        }

        public static string GenerateOrderNumber()
        {
            var date = DateTime.Now;
            var rd = new Random().Next(1, 99);
            return  "{0}{1}".FormatWith(date.ToString("yyMMddHHmmssfff"), rd.ToString("00"));
        }

        #endregion
    }
}